<?php
/**
 * DownGoods.php class file.
 * @author wudg <544038230@qq.com>
 * @date 2020/12/27- 下午5:40
 */

namespace common\jobs\copy;


use common\constants\BaseConst;
use common\constants\CopyConst;
use common\jobs\dao\PddCopyLogDao;
use common\jobs\dao\PddCopyProductsDao;
use common\exception\CopyException;
use common\components\misc\ImportLogger;
use common\constants\PlatformConst;
use common\dao\ComSpiderDao;
use common\dao\PddCopyProductsRefoundDao;
use common\drivers\SpiderProductDriver;
use common\drivers\SpiderProductDriverGY;
use common\exception\DriverException;
use common\exception\TaskException;
use common\helpers\JobHelper;
use common\helpers\StringHelper;
use common\models\com\ComSpider;
use console\components\helpers\ConsoleHelper;
use Littlesqx\AintQueue\JobMiddlewareInterface;
use Littlesqx\AintQueue\JobInterface;
use yii\base\Exception;
use common\models\es\EsCopyProducts;
use yii\helpers\FileHelper;
use Yii;

class CopyGoodsToSpider extends CopyBase implements \common\drivers\interfaces\JobInterface
{
    /**
     * 参数组装
     * @var array
     */
    public $args = [];

    /**
     * 日志详细
     * @var \api\models\PddCopyProducts|null
     */
    public $logInfo;


    /**
     * 批次详细
     * @var \api\models\PddCopyLogs|null
     */
    public $batchInfo;


    /**
     * 取缓存时间
     * @var float|int
     */
    public $cacheTime = 86400;

    /**
     * 取缓存时间
     * @var float|int
     */
    public $cacheTimes = 86400;


    /**
     * CopyGoodsToSpider constructor.
     * @param $args
     */
    public function __construct($args)
    {
        $this->args = $args;

        $this->cacheSuccessKey .= $this->args['batch_id'];
        $this->cacheErrorKey .= $this->args['batch_id'];
        $this->totalCacheKey .= $this->args['batch_id'];

    }


    /**
     * 获取下载数据对应驱动
     * @param int $platform
     * @return string|null
     */
    private function _getDriver(int $platform)
    {
        $platformList = [
            PlatformConst::PLATFORM_TB => 'TaobaoSpider', //淘宝
            PlatformConst::PLATFORM_1688 => 'OfferSpider',   //1688
            PlatformConst::PLATFORM_TMALL => 'TmallSpider',  //天猫
            PlatformConst::PLATFORM_PDD => 'ApiSpider',  //拼多多，后期为所有货源数据
        ];

        return $platformList[$platform] ?? null;
    }


//    /**
//     * 处理队列
//     * @return mixed|void
//     */
//    public function handle() :void
//    {
//
//        try {
//
//            Yii::$app->db->open();
//            $this->logger = new ImportLogger($this->_createFilePath());
//            $this->batchInfo = (new PddCopyLogDao())->getBatchInfoByPk($this->args['batch_id']);
//
//            if(!$this->batchInfo)
//            {
//                throw new CopyException('批次号不存在');
//            }
//
//            $this->logInfo = (new PddCopyProductsDao())->getInfoByPk($this->args['log_id']);
//
//            if(!$this->logInfo)
//            {
//                throw new CopyException('日志不存在');
//            }
//
//            /**
//             * 任务已取消，不做任何操作,直接返回
//             */
//            if(in_array($this->logInfo->status,[CopyConst::COPY_CANCEL])  )
//            {
//                $this->_showLog('任务已取消，不做任何处理');
//                return;
//            }
//
//            if($this->logInfo->is_delete == BaseConst::DELETED)
//            {
//                $this->_showLog('任务已被删除，不做任何处理');
//                return;
//            }
//
//            if(!isset($this->args['platform']) || empty($this->args['platform']))
//            {
//                throw new CopyException('平台分析失败');
//            }
//
//            if(!isset($this->args['num_iid']) || empty($this->args['num_iid']))
//            {
//                throw new CopyException('分析平台唯一标识失败');
//            }
//            $drivers = $this->_getDriver($this->args['platform']);
//
//            if(!$drivers)
//            {
//                throw new CopyException('驱动获取失败');
//            }
//            //$driverFilter = (new SpiderProductDriver())->getSpiderDriver($drivers);
//            $driverFilter = (new SpiderProductDriverGY())->getSpiderDriver('ApiSpider');
//            $spiderInfo = (new ComSpiderDao())->getByPlatAndNumId($this->args['platform'], $this->args['num_iid']);
//
//            if(!$spiderInfo)
//            {
//                $spiderInfo = new ComSpider();
//            }
//            $spiderInfo->platform = $this->args['platform'];
//            $spiderInfo->plat_id = $this->args['num_iid'];
//
//
//            //从缓存走
//            if(isset($spiderInfo) && $spiderInfo->lasttime_at + $this->cacheTime > time())
//            {
//                $this->_showLog('使用缓存数据');
//            }else{
//
//                /**
//                 * 获取采集内容
//                 */
//                $driverFilter->getContents($this->args['url']);
//
//
//                $this->_showLog('获取页面数据完成:'.$this->args['url']);
////                $spiderInfo->lasttime_at = time();
////                $spiderInfo->extend_data = StringHelper::jsonEncode($driverFilter->formatContents());
////                $this->_showLog('分析页面数据完成');
////                $spiderInfo->note = StringHelper::jsonEncode($driverFilter->getErrorInfo());
////                $result = $spiderInfo->save();
////                if (!$result) {
////                    $this->_showLog('写入采集日志表异常,异常原因:'.$spiderInfo->errorsToOneString());
////                    throw new CopyException('写入采集日志表异常,异常原因:'.$spiderInfo->errorsToOneString());
////                }
//            }
////            $this->_showLog('成功写入采集日志表');
////            $this->logInfo->status = CopyConst::COPY_SPIDER_YES;
////            $this->logInfo->save();
////
////            switch ($this->args['callback']) {
////                //直接上货
////                case 'copyToPdd':
////                    $jobArgs = [
////                        'log_id' => $this->args['log_id'], // 日志表主键
////                        'batch_id' => $this->args['batch_id'],// 批次号id
////                        'spider_id' => $spiderInfo->id, //com_spider 表主键
////                        'filter_id' => $this->args['filter_id'], //pdd_filter_tpl 表主键
////                        'uid' => $this->args['uid'],// uid
////                        'mall_id' =>$this->args['mall_id'] //店铺id
////                    ];
////                    $this->_showLog('投递到[上货任务],传递参数'.StringHelper::jsonEncode($jobArgs));
////                    JobHelper::toCopy($jobArgs);
////                    break;
////                //搬家到云库
////                case 'copyToCloud':
////                    $jobArgs = [
////                        'log_id' => $this->args['log_id'], // 日志表主键
////                        'batch_id' => $this->args['batch_id'],// 批次号id
////                        'spider_id' => $spiderInfo->id, //com_spider 表主键
////                        'filter_id' => $this->args['filter_id'], //pdd_filter_tpl 表主键
////                        'uid' => $this->args['uid'],// uid
////                        'store_id' => $this->args['store_id'] ?? 0,// 所属仓库
////                        'mall_id' =>$this->args['mall_id'] //店铺id
////                    ];
////                    $this->_showLog('投递到[入云库任务],传递参数'.StringHelper::jsonEncode($jobArgs));
////                    JobHelper::toCloud($jobArgs);
////                    break;
////                default:
////                    throw new CopyException('暂无设置其他任务');
////            }
//        }catch (CopyException $e)
//        {
//            $this->_showLog('[流程相关]抓取数据异常->'.$e->getMessage());
//            $this->setErrorNum();
//            $this->logInfo->error_info = substr($e->getMessage(),0,240);
//            $this->saveLog([
//                'status' =>  CopyConst::COPY_FAILED,
//                'product_status' =>  0
//            ]);
//        }catch (TaskException $e)
//        {
//            $this->_showLog('[任务相关]抓取数据异常->'.$e->getMessage());
//            $this->setErrorNum();
//            $this->logInfo->error_info = substr($e->getMessage(),0,240);
//            $this->saveLog([
//                'status' =>  CopyConst::COPY_FAILED,
//                'product_status' =>  0
//            ]);
//        }catch (DriverException $e)
//        {
//            $this->_showLog('[采集相关]驱动任务处理失败->'.$e->getMessage());
//            $this->setErrorNum();
//            $this->logInfo->error_info = substr($e->getMessage(),0,240);
//            $this->saveLog([
//                'status' =>  CopyConst::COPY_FAILED,
//                'product_status' =>  0
//            ]);
//        }catch (\yii\db\Exception $e)
//        {
//            $this->_showLog('[数据库相关]驱动任务处理失败->'.$e->getMessage());
//            $this->setErrorNum();
//            $this->logInfo->error_info = substr($e->getMessage(),0,240);
//            $this->saveLog([
//                'status' =>  CopyConst::COPY_FAILED,
//                'product_status' =>  0
//            ]);
//        }catch (Exception $e)
//        {
//
//            $this->_showLog($e->getMessage());
//            $this->setErrorNum();
//            $this->logInfo->error_info = substr($e->getMessage(),0,240);
//            $this->saveLog([
//                'status' =>  CopyConst::COPY_FAILED,
//                'product_status' =>  0
//            ]);
//        }catch (\ErrorException $e)
//        {
//            $this->_showLog($e->getMessage());
//            $this->setErrorNum();
//            $this->logInfo->error_info = substr($e->getMessage(),0,240);
//            $this->saveLog([
//                'status' =>  CopyConst::COPY_FAILED,
//                'product_status' =>  0
//            ]);
//        }
//        Yii::$app->db->close();
//    }

    /**
     * 文件日志记录
     * @param $msg
     * @throws ServicesException
     */
    public function writeSpiderLog($msg)
    {

        $path = Yii::getAlias('@runtime/api/spider_crawler_execule/');

        //目录如果不存就先创建目录
        if (!is_dir($path)) {
            FileHelper::createDirectory($path);
        }

        $cp = fopen($path . 'log-' . date('Ymd H:i') . '.log', "a+");
        $txt = "【" . date('Y-m-d H:i:s', time()) . "】---" . $msg . "\r\n";
        fwrite($cp, $txt);
        fclose($cp);

    }

    public function writeSpiderLog1($msg)
    {

        $path = Yii::getAlias('@runtime/api/spider_crawler_execule1/');

        //目录如果不存就先创建目录
        if (!is_dir($path)) {
            FileHelper::createDirectory($path);
        }

        $cp = fopen($path . 'log-' . date('Ymd H:i') . '.log', "a+");
        $txt = "【" . date('Y-m-d H:i:s', time()) . "】---" . $msg . "\r\n";
        fwrite($cp, $txt);
        fclose($cp);

    }

    /**
     * 处理队列
     * @return mixed|void
     */
    public function handle(): void
    {


        try {
            Yii::$app->db->open();
            $this->logger = new ImportLogger($this->_createFilePath());
            $this->batchInfo = (new PddCopyLogDao())->getBatchInfoByPk($this->args['batch_id']);
            if (!$this->batchInfo) {
                throw new CopyException('批次号不存在');
            }

            if (!isset($this->args['platform']) || empty($this->args['platform'])) {
                throw new CopyException('平台分析失败');
            }

            if (!isset($this->args['num_iids']) || empty($this->args['num_iids'])) {
                throw new CopyException('分析平台唯一标识失败');
            }
            $drivers = $this->_getDriver($this->args['platform']);
            if (!$drivers) {
                throw new CopyException('驱动获取失败');
            }
            $driverFilter = (new SpiderProductDriverGY())->getSpiderDriver('ApiSpider');
            $num_idds_arr_old = explode(',', $this->args['num_iids']);
            if ($num_idds_arr_old) {
                foreach ($num_idds_arr_old as $k => $v) {
                    $spiderInfo = (new ComSpiderDao())->getByPlatAndNumId($this->args['platform'], $v);
                    if (isset($spiderInfo) && $spiderInfo->lasttime_at + $this->cacheTimes > time()) {
                        $this->_showLog('使用缓存数据::');
                        $logInfo = (new PddCopyProductsDao())->getInfoById($this->args['batch_id'], $v);
                        //取消跳过
                        if ($logInfo->status == CopyConst::COPY_CANCEL) {
                            unset($num_idds_arr_old[$k]);
                            $this->writeSpiderLog('该任务已经取消');
                            continue;
                        }

                        $logInfo->status = CopyConst::COPY_SPIDER_YES;
                        if ($logInfo) {
                            $logInfo->save();
                        }
                        //同步es
//                        $idsArr = [$logInfo->id];
//                        $es = new EsCopyProducts();
//                        $es->updateByfield($idsArr,['status'=>CopyConst::COPY_SPIDER_YES]);
                        switch ($this->args['callback']) {
                            //直接上货
                            case 'copyToPdd':
                                $jobArgs = [
                                    'log_id' => $logInfo->id, // 日志表主键
                                    'batch_id' => $logInfo->batch_no,// 批次号id
                                    'spider_id' => $spiderInfo->id, //com_spider 表主键
                                    'filter_id' => $logInfo->tpl_id, //pdd_filter_tpl 表主键
                                    'uid' => $logInfo->uid,// uid
                                    'mall_id' => $logInfo->mall_id //店铺id
                                ];
                                JobHelper::toCopy($jobArgs);
                                break;
                            //搬家到云库
                            case 'copyToCloud':
                                $jobArgs = [
                                    'log_id' => $logInfo->id, // 日志表主键
                                    'batch_id' => $logInfo->batch_no,// 批次号id
                                    'spider_id' => $spiderInfo->id, //com_spider 表主键
                                    'filter_id' => $logInfo->tpl_id, //pdd_filter_tpl 表主键
                                    'uid' => $logInfo->uid,// uid
                                    'store_id' => $logInfo->store_id,// 所属仓库
                                    'mall_id' => $logInfo->mall_id //店铺id
                                ];
                                JobHelper::toCloud($jobArgs);
                                break;
                            default:
                                throw new CopyException('暂无设置其他任务');
                        }
                        unset($num_idds_arr_old[$k]);
                    }
                }
            }

            if ($num_idds_arr_old) {
                $this->args['num_iids'] = implode(',', $num_idds_arr_old);
                //从缓存走
                $contents = $driverFilter->getContent($this->args['num_iids'], $this->args['platform']);
                if ($contents) {
                    if (!isset($contents['list']['request_id'])) {
                        $this->_showLog('采集数据失败' . StringHelper::jsonEncode($contents));
                    } else {
                        if (isset($contents['list']['goodsItem']) && !empty($contents['list']['goodsItem'])) {
                            foreach ($contents['list']['goodsItem'] as $k => $v) {
                                $logInfo = (new PddCopyProductsDao())->getInfoById($this->args['batch_id'], $v['goods_id']);
                                $logInfo->status = CopyConst::COPY_SPIDER_YES;
                                $logInfo->store_id = $this->args['store_id'] ? $this->args['store_id'] : 0;
                                $logInfo->request_id = $contents['list']['request_id'];
                                $logInfo->callback = $this->args['callback'];
                                if ($logInfo) {
                                    $logInfo->save();
                                }
                                $spiderInfo = (new ComSpiderDao())->getByPlatAndNumId($v['platform'], $v['goods_id']);
                                if (!$spiderInfo) {
                                    $spiderInfo = new ComSpider();
                                }
                                $spiderInfo->platform = $v['platform'];
                                $spiderInfo->plat_id = $v['goods_id'];
                                $spiderInfo->lasttime_at = time();
                                $spiderInfo->extend_data = StringHelper::jsonEncode($driverFilter->formatContent($v));
                                if (!Yii::$app->db->isActive) {
                                    Yii::$app->db->open();
                                }
                                $spiderInfo->note = StringHelper::jsonEncode($driverFilter->getErrorInfo());
                                $result = $spiderInfo->save();
                                Yii::$app->db->close();
                                if ($logInfo) {
                                    switch ($logInfo->callback) {
                                        //直接上货
                                        case 'copyToPdd':
                                            $jobArgs = [
                                                'log_id' => $logInfo->id, // 日志表主键
                                                'batch_id' => $logInfo->batch_no,// 批次号id
                                                'spider_id' => $spiderInfo->id, //com_spider 表主键
                                                'filter_id' => $logInfo->tpl_id, //pdd_filter_tpl 表主键
                                                'uid' => $logInfo->uid,// uid
                                                'mall_id' => $logInfo->mall_id //店铺id
                                            ];
                                            JobHelper::toCopy($jobArgs);
                                            break;
                                        //搬家到云库
                                        case 'copyToCloud':
                                            $jobArgs = [
                                                'log_id' => $logInfo->id, // 日志表主键
                                                'batch_id' => $logInfo->batch_no,// 批次号id
                                                'spider_id' => $spiderInfo->id, //com_spider 表主键
                                                'filter_id' => $logInfo->tpl_id, //pdd_filter_tpl 表主键
                                                'uid' => $logInfo->uid,// uid
                                                'store_id' => $logInfo->store_id,// 所属仓库
                                                'mall_id' => $logInfo->mall_id //店铺id
                                            ];
                                            JobHelper::toCloud($jobArgs);
                                            break;
                                        default:
                                            throw new CopyException('暂无设置其他任务');
                                    }

                                }
                            }
                            $this->_showLog('成功采集到数据');
                        } else {
                            $num_idds_arr = explode(',', $this->args['num_iids']);
                            if ($num_idds_arr) {
                                foreach ($num_idds_arr as $k => $v) {
                                    if ($contents['list']['request_id']) {
                                        $logInfo = (new PddCopyProductsDao())->getInfoByIdRequest($this->args['batch_id'], $v);
                                        $logInfo->store_id = $this->args['store_id'] ? $this->args['store_id'] : 0;
                                        $logInfo->request_id = $contents['list']['request_id'];
                                        $logInfo->callback = $this->args['callback'];
                                        if ($logInfo) {
                                            $logInfo->save();
                                        }
                                        (new PddCopyProductsRefoundDao())->insertData([
                                            'request_id' => $contents['list']['request_id'],
                                            'mall_id' => $logInfo->mall_id,
                                            'goods_id' => $logInfo->num_iid,
                                            'copyid' => $logInfo->id,
                                            'platform' => $this->args['platform'],
                                            'create_time' => time(),
                                            'update_time' => time()
                                        ]);
                                    }
                                }
                            }
                        }
                    }
                } else {
                    $this->_showLog('采集失败');
                }
            }


        } catch (CopyException $e) {
            $this->_showLog('[流程相关]抓取数据异常->' . $e->getMessage());
            $this->setErrorNum();
        } catch (TaskException $e) {
            $this->_showLog('[任务相关]抓取数据异常->' . $e->getMessage());
            $this->setErrorNum();
        } catch (DriverException $e) {
            $this->_showLog('[采集相关]驱动任务处理失败->' . $e->getMessage());
            $this->setErrorNum();
        } catch (\yii\db\Exception $e) {
            $this->_showLog('[数据库相关]驱动任务处理失败->' . $e->getMessage());
            $this->setErrorNum();;
        } catch (Exception $e) {

            $this->_showLog($e->getMessage());
            $this->setErrorNum();
        } catch (\ErrorException $e) {
            $this->_showLog($e->getMessage());
            $this->setErrorNum();
        } finally {
            Yii::$app->db->close();
        }
    }

    /**
     * @inheritDoc
     */
    public function filter()
    {
        return true;
    }

    /**
     * @inheritDoc
     */
    public function copy()
    {
        return true;
    }

    /**
     * 采集log目录初始化
     * @return bool|string
     * @throws \yii\base\Exception
     */
    protected function _createFilePath()
    {
        $path = Yii::getAlias('@runtime/job/spider/');

        if (!is_dir($path)) {
            FileHelper::createDirectory($path);
        }

        return $path;
    }


    /**
     * 日志展示
     * @param $msg
     */
    private function _showLog($msg)
    {
        ConsoleHelper::runInfo($this->args['batch_id'] . ':spider:' . $msg);
        $this->logger->add($this->args['batch_id'] . ':spider:' . $msg);
    }

    /**
     * @inheritDoc
     */
    public function canRetry(int $attempt, $error): bool
    {
        return false;
    }

    /**
     * @inheritDoc
     */
    public function retryAfter(int $attempt): int
    {
        return 0;
    }

    /**
     * @inheritDoc
     */
    public function failed(int $id, array $payload): void
    {
        // TODO: Implement failed() method.
    }

    /**
     * @inheritDoc
     */
    public function middleware(): array
    {
        return [];
    }

}